<template>
  <div class="chat-container">
    <!-- 左侧聊天历史列表 -->
    <div class="chat-history">
      <div class="history-header">
        <h2>聊天记录</h2>
        <el-button type="primary" size="large" @click="startNewChat">
          <el-icon><Plus /></el-icon>新对话
        </el-button>
      </div>
      <div class="history-list">
        <div
          v-for="chat in chatHistory"
          :key="chat.id"
          class="history-item"
          :class="{ active: currentChatId === chat.id }"
          @click="selectChat(chat.id)"
        >
          <el-icon><ChatDotRound /></el-icon>
          <span class="chat-title">{{ chat.title || `对话 ${chat.id.substring(0, 8)}` }}</span>
          <span class="chat-time">{{ new Date(chat.timestamp || Date.now()).toLocaleDateString() }}</span>
        </div>
      </div>
    </div>

    <!-- 右侧聊天对话框 -->
    <div class="chat-main">
      <div class="chat-messages" ref="messageContainer">
        <div v-if="currentChat.messages.length === 0" class="empty-chat">
          <el-empty description="暂无聊天记录，开始新的对话吧！" />
        </div>
        <div v-for="msg in currentChat.messages" :key="msg.id" class="message" :class="msg.role">
          <div class="message-content">
            <div class="avatar">
              <el-avatar :size="40" :src="msg.role === 'user' ? userAvatar : aiAvatar" />
            </div>
            <div class="message-body">
              <div class="text markdown-content" v-html="formatMessage(msg.content)" ref="contentRef"></div>
              <div class="message-actions">
                <el-button
                  type="text"
                  size="small"
                  class="copy-button"
                  @click="copyMessage(msg.content)"
                  :title="copied ? '已复制' : '复制内容'"
                >
                  <el-icon><Document /></el-icon>
                </el-button>
              </div>
            </div>
          </div>
        </div>
      </div>
     
      <!-- 输入框区域 -->
      <div class="chat-input">
        <div v-if="selectedFiles.length > 0" class="selected-files">
          <div v-for="(file, index) in selectedFiles" :key="index" class="file-item">
            <span class="file-name">{{ file.name }}</span>
            <span class="file-size">({{ formatFileSize(file.size) }})</span>
            <el-button type="text" @click="removeFile(index)">
              <el-icon><Close /></el-icon>
            </el-button>
          </div>
        </div>

        <div class="input-wrapper">
          <input
            type="file"
            ref="fileInput"
            @change="handleFileUpload"
            accept="image/*,audio/*,video/*"
            multiple
            class="hidden"
          >
          <el-button
            type="text"
            class="upload-button"
            @click="triggerFileInput"
            :disabled="isLoading"
          >
            <el-icon><Paperclip /></el-icon>
          </el-button>

          <el-input
            v-model="inputMessage"
            type="textarea"
            :rows="3"
            placeholder="输入消息..."
            resize="none"
            @keyup.enter.prevent="sendMessage"
          />
          
          <el-button 
            type="primary" 
            @click="sendMessage" 
            :disabled="!canSendMessage"
            :loading="isLoading"
          >
            {{ isLoading ? '发送中...' : '发送' }}
          </el-button>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, nextTick, computed, onBeforeUnmount } from 'vue'
import { Plus, ChatDotRound, Document, Close, Paperclip } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'
import { marked } from 'marked'
import DOMPurify from 'dompurify'
import hljs from 'highlight.js'
import 'highlight.js/styles/github-dark.css'
import {useUserStore} from '@/store/user'

const userStore = useUserStore()

// 头像
const userAvatar = 'https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png'
const aiAvatar = 'https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png'

// 状态变量
const chatHistory = ref([])
const currentChatId = ref('')
const currentChat = ref({ messages: [] })
const inputMessage = ref('')
const messageContainer = ref(null)
const isLoading = ref(false)
const copied = ref(false)
const selectedFiles = ref([])
const fileInput = ref(null)
const eventSource = ref(null)
const baseURL = 'http://127.0.0.1:3000' // 修改为后端地址

// 计算属性
const canSendMessage = computed(() => {
  return (inputMessage.value.trim() || selectedFiles.value.length > 0) && !isLoading.value
})

// 配置marked
marked.setOptions({
  highlight: function(code, lang) {
    if (lang && hljs.getLanguage(lang)) {
      return hljs.highlight(code, { language: lang }).value
    }
    return hljs.highlightAuto(code).value
  },
  breaks: true,
  gfm: true
})

// 格式化消息内容
const formatMessage = (content) => {
  if (!content) return ''
  const html = marked(content)
  return DOMPurify.sanitize(html)
}

// 格式化文件大小
const formatFileSize = (bytes) => {
  if (bytes === 0) return '0 B'
  const k = 1024
  const sizes = ['B', 'KB', 'MB', 'GB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return `${(bytes / Math.pow(k, i)).toFixed(2)} ${sizes[i]}`
}

// 复制消息内容
const copyMessage = async (content) => {
  try {
    await navigator.clipboard.writeText(content)
    copied.value = true
    setTimeout(() => copied.value = false, 2000)
    ElMessage.success('复制成功')
  } catch (error) {
    ElMessage.error('复制失败')
  }
}

// 文件处理相关方法
const triggerFileInput = () => {
  fileInput.value.click()
}

const handleFileUpload = (event) => {
  const files = Array.from(event.target.files)
  selectedFiles.value.push(...files)
  event.target.value = ''
}

const removeFile = (index) => {
  selectedFiles.value.splice(index, 1)
}

// 获取聊天历史列表
const fetchChatHistory = async () => {
  try {
    const response = await fetch(`${baseURL}/ai/history/chat`,{
                    headers: {
                        Authorization: 'Bearer ' + userStore.token,
                    }
                  })
    if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`)
    const data = await response.json()
    chatHistory.value = data.map(id => ({
      id,
      title: `对话 ${id.slice(-6)}`,
      timestamp: Date.now()
    }))
    if (data.length > 0 && !currentChatId.value) {
      selectChat(data[0])
    }
  } catch (error) {
    console.error('获取聊天历史失败:', error)
    ElMessage.error('获取聊天历史失败，请稍后重试')
  }
}

// 获取特定聊天的消息历史
const fetchChatMessages = async (chatId) => {
  try {
    const response = await fetch(`${baseURL}/ai/history/chat/${chatId}`,{
                      headers: {
                        Authorization: 'Bearer ' + userStore.token,
                    }
    })
    if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`)
    const messages = await response.json()
    currentChat.value.messages = messages.map((msg, index) => ({
      id: `${chatId}-${index}`,
      role: msg.role,
      content: msg.content,
      timestamp: msg.timestamp || Date.now()
    }))
    await scrollToBottom()
  } catch (error) {
    console.error('获取聊天消息失败:', error)
    ElMessage.error('获取聊天消息失败，请稍后重试')
  }
}

// 开始新对话
const startNewChat = () => {
  const newChatId = Date.now().toString()
  currentChatId.value = newChatId
  currentChat.value = { messages: [] }
  
  chatHistory.value.unshift({
    id: newChatId,
    title: `对话 ${newChatId.slice(-6)}`,
    timestamp: Date.now()
  })
  
  ElMessage.success('已创建新对话')
}

// 选择对话
const selectChat = async (chatId) => {
  if (currentChatId.value === chatId) return
  currentChatId.value = chatId
  await fetchChatMessages(chatId)
}

// 滚动到底部
const scrollToBottom = async () => {
  await nextTick()
  if (messageContainer.value) {
    messageContainer.value.scrollTop = messageContainer.value.scrollHeight
  }
}

// 发送消息
const sendMessage = async () => {
  if (!canSendMessage.value) return
  
  if (!currentChatId.value) {
    startNewChat()
  }
  
  const formData = new FormData()
  if (inputMessage.value.trim()) {
    formData.append('prompt', inputMessage.value.trim())
  }
  selectedFiles.value.forEach(file => {
    formData.append('files', file)
  })
  
  // 添加用户消息
  const userMessage = {
    id: `${currentChatId.value}-${Date.now()}`,
    role: 'user',
    content: inputMessage.value.trim(),
    timestamp: Date.now()
  }
  currentChat.value.messages.push(userMessage)
  
  // 清空输入
  inputMessage.value = ''
  selectedFiles.value = []
  
  await scrollToBottom()
  
  try {
    isLoading.value = true
    
    // 添加AI回复占位
    const aiMessage = {
      id: `${currentChatId.value}-${Date.now()}-ai`,
      role: 'assistant',
      content: '',
      timestamp: Date.now()
    }
    currentChat.value.messages.push(aiMessage)
    
    // 发送 HTTP 请求
    const url = new URL(`${baseURL}/ai/chat`)
    url.searchParams.append('chatId', currentChatId.value)
    url.searchParams.append('prompt', formData.get('prompt'))

    const response = await fetch(url, {
      method: 'GET',
      headers: {
         Authorization: 'Bearer ' + userStore.token,
      }
    })

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`)
    }

    const reader = response.body.getReader()
    const decoder = new TextDecoder()

    let timeoutId = setTimeout(() => {
      reader.cancel()
      ElMessage.error('响应超时，请重试')
      isLoading.value = false
    }, 30000)
    
    
    try {
      let streaming = true
      while (streaming) {
        const { value, done } = await reader.read()
        
        if (done) {
          streaming = false
          break
        }
        
        clearTimeout(timeoutId)
        const text = decoder.decode(value)
        const lastMessage = currentChat.value.messages[currentChat.value.messages.length - 1]
        lastMessage.content += text
        await scrollToBottom()
        
        // 重置超时计时器
        timeoutId = setTimeout(() => {
          streaming = false
          reader.cancel()
          ElMessage.error('响应超时，请重试')
          isLoading.value = false
        }, 30000)
      }
    } finally {
      clearTimeout(timeoutId)
      isLoading.value = false
    }
    
  } catch (error) {
    console.error('发送消息失败:', error)
    ElMessage.error('发送消息失败，请重试')
    isLoading.value = false
  }
}

// 生命周期钩子
onMounted(() => {
  fetchChatHistory()
})

onBeforeUnmount(() => {
  if (eventSource.value) {
    eventSource.value.close()
  }
})
</script>

<style scoped>
.chat-container {
  display: flex;
  height: 100vh;
  background-color: #f5f7fa;
}

.chat-history {
  width: 260px;
  border-right: 1px solid #dcdfe6;
  background-color: #fff;
  display: flex;
  flex-direction: column;
}

.history-header {
  padding: 16px;
  border-bottom: 1px solid #dcdfe6;
}

.history-list {
  flex: 1;
  overflow-y: auto;
  padding: 8px;
}

.history-item {
  padding: 12px;
  cursor: pointer;
  border-radius: 4px;
  margin-bottom: 4px;
  display: flex;
  align-items: center;
  gap: 8px;
}

.history-item:hover {
  background-color: #f5f7fa;
}

.history-item.active {
  background-color: #ecf5ff;
  color: #409eff;
}

.chat-main {
  flex: 1;
  display: flex;
  flex-direction: column;
  padding: 20px;
}

.chat-messages {
  flex: 1;
  overflow-y: auto;
  padding: 16px;
  background-color: #fff;
  border-radius: 8px;
  margin-bottom: 20px;
}

.message {
  margin-bottom: 24px;
}

.message-content {
  display: flex;
  gap: 12px;
}

.message-body {
  flex: 1;
  background-color: #f5f7fa;
  padding: 12px;
  border-radius: 8px;
}

.user .message-body {
  background-color: #ecf5ff;
}

.markdown-content {
  line-height: 1.6;
}

.markdown-content pre {
  background-color: #282c34;
  padding: 16px;
  border-radius: 4px;
  overflow-x: auto;
}

.message-actions {
  margin-top: 8px;
  display: flex;
  justify-content: flex-end;
}

.chat-input {
  background-color: #fff;
  border-radius: 8px;
  padding: 16px;
}

.selected-files {
  margin-bottom: 12px;
}

.file-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 8px;
  background-color: #f5f7fa;
  border-radius: 4px;
  margin-bottom: 4px;
}

.input-wrapper {
  display: flex;
  gap: 8px;
  align-items: flex-start;
}

.hidden {
  display: none;
}

.empty-chat {
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}
</style>